#include <bits/stdc++.h>
using namespace std;
int n, m;
#define clr(a) memset(a, 0, sizeof a)
const int MN = 1100000, SIG = 40;
int tr[MN][SIG+5], id[256], child[MN], sz, val[MN], hasj[MN], hasw[MN];
inline bool is_rule(char ch){
    if(islower(ch) || isdigit(ch) || ch=='*' || ch=='#' || ch=='-' || ch=='.')
        return true;
    else return false;
}

inline bool is_vpn(char ch){
    if(islower(ch) || isdigit(ch) || ch=='-')
        return true;
    else return false;
}


bool can_rule(const string &s){
    for (int i = 0; i < s.size(); ++i){
        if(!is_rule(s[i])) return false;
        if(s[i]=='-'){
            if(i==0 || i==s.size()-1) return false;
            if(!(islower(s[i-1]) && islower(s[i+1]))) return false;
        }
    }
    if(s.front() == '.' || s.back() == '.') return false;
    for(int i=1; i<s.size(); ++i) if(s[i]=='.' && s[i-1]=='.' || s[i]=='*' || s[i]=='#') return false;
    if(s.front()=='*' || s.front()=='#') return s.size()==1 || s[1]=='.';
    return true;
}

bool can_vpn(const string &s){
    for (int i = 0; i < s.size(); ++i){
        if(!is_vpn(s[i])) return false;
        if(s[i]=='-'){
            if(i==0 || i==s.size()-1) return false;
            if(!(islower(s[i-1]) && islower(s[i+1]))) return false;
        }
    }
    if(s.front()=='-' || isdigit(s.front())) return false;
    return true;
}

bool empty(int u){
    for (int i = 0; i < SIG; ++i) {
        if(tr[u][i]) return false;
    }
    return true;
}

void add(const string &s){
    int p = 0;
//    bool j = s.front()=='#', w = s.front()=='*';
//    int nx = tr[p][id[s[0]]];
//    if(j && hasj[nx]) return;
//    if(w && hasw[nx]) return;
    for (int i = s.size()-1; i >= 0; --i) {
        int c = id[s[i]];
        int &nx = tr[p][c];
        if(!nx){
//            if(s[i]=='*' && !empty(p)) return;
            ++sz, clr(tr[0]), val[sz] = 0, nx=sz;
        }
        p = nx;
    }
    if(!val[p]) val[p]=1;

}

int query(const string &s){
    int p = 0;
    for (int i = s.size()-1; i >=0 ; --i) {
        int j = id[s[i]];
        if(tr[p][j]) p = tr[p][j];
        else return 0;
    }
    if(s.front()=='*') return child[p];
    else return 1;
}

int find_child(int p){
    bool leaf = true;
    for (int i = 0; i < SIG; ++i) {
        if(tr[p][i])
            child[p] += find_child(tr[p][i]), leaf = false;
    }
    if(leaf) return val[p];
    else return child[p];
}

void init(){
    sz = 0;
    clr(tr[0]);
    memset(hasj, false, sizeof hasj);
    memset(hasw, false, sizeof hasw);
}

int main() {
    int t = 0;
    for(int i=0; i<26; ++i) id[i+'a'] = t++;
    for(int i=0; i<10; ++i) id[i+'0'] = t++;
    id[t++] = '-', id[t++] = '.';
    while(cin >> n){
        init();
        for (int i = 0; i < n; ++i) {
            string rule, vpn; cin >> rule >> vpn;
            if(can_rule(rule) && can_vpn(vpn)){
                add(rule);
            }
        }
        find_child(0);
        for (int i = 0; i < m; ++i) {
            string s; cin >> s;
            cout << query(s) << '\n';
        }
    }
    return 0;
}